package com.zipking.cloud.springbootmybatis.callback;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

public class CompletableFutureCallback {

        public static void main(String[] args) throws ExecutionException, InterruptedException {
            ExecutorService threadPool = Executors.newFixedThreadPool(2);
            try {
                CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName() + "----come in");
                    int result = ThreadLocalRandom.current().nextInt(10);
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("1s后出结果 " + result);
                    return result;
                },threadPool).whenComplete((v,e) -> {
                    //v表示上一阶段，e是异常
                    if(e == null){
                        //这里代表一切顺利
                        System.out.println("-----计算完成，更新数值： " + v);
                    }
                }).exceptionally(e -> {
                    e.printStackTrace();
                    System.out.println("异常情况：" + e.getCause() + "\t" + e.getMessage());
                    return null;
                });
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                threadPool.shutdown();
            }


            System.out.println(Thread.currentThread().getName() + "线程先去忙其他任务");
    }
    /**
     * 借助 CompletableFuture 来实现异步行为。
     * 不会抛出异常，在 onFailure 中处理异常
     *
     * @param executeTask
     * @param <R>
     * @return
     */
    /*private static <R> CompletableFuture<R> doInvoker(
            CallbackTask<R> executeTask) {
        CompletableFuture<R> invoke = CompletableFuture
                .supplyAsync(() -> {
                    try {
                        return executeTask.execute();
                    } catch (Exception exception) {
                        throw new BizException(
                                ASYNC_INVOKER_ERROR.getErrorCode(),
                                exception.getMessage());
                    }
                }, gPool)
                .whenComplete((result, throwable) -> {
                    // 不管成功与失败，whenComplete 都会执行，
                    // 通过 throwable == null 跳过执行
                    if (throwable == null) {
                        executeTask.onSuccess(result);
                    }
                })
                .exceptionally(throwable -> {
                    executeTask.onFailure(throwable);
                    // todo 给一个默认值，或者使用 Optional包装一下，否者异常会出现NPE
                    return null;
                });
        return invoke;
    }*/
}
